<?php
	/**
	 * 分页类
	 * @author haifeng
	 * @date   20141009
	 */
	class Pager{
		const SFIRST = 'f';
		const SINFO = 'i';
		const STOTAL = 't';
		const SRECORD = 'r';
		const SPREV = 'p';
		const SCODE = 'c';
		const SNEXT = 'n';
		const SLAST = 'l';
		const SSELECT = 's';
	
		protected $pageSize = 15;	//每页显示条数
		protected $totals;			//总记录数
		protected $totalPages;		//总页数
		protected $currentPage = 1;		//当前页码
		protected $showStyle = 'fpcnl';	//显示样式 i:info 当前页码/总页码 t:total 总记录数 r:record 每页记录数
									//f:first 首页 p:prev 上一页 c:code 页码 n:next 下一页 l:last 尾页 s:select 下拉 
		protected $maxPage = 10;	//超过多少页显示省略符
		protected $offset = 2;		//省略符的偏移量
		protected $middlePage = 6;	//省略符之间显示的页码个数
		protected $pageName = 'p';	//分页参数名称
		protected $pageSizeOnlyRead = true;//每页记录条数是否只读
		protected $lang = array(
                                'info'=>"当前第<em>__CURRENTPAGE__}</em>页/共<em>__TOTALPAGES__</em>页\n",
                                'total'=>"<span> 总计:__TOTALS__条记录</span>\n",
                                'record'=>"<span>每页__PAGESIZE__条记录</span>",
                                'first'=>"<span>__FIRST__</span>",
                                'prev'=>"<span>__PREV__</span>",
                                'code'=>"<li>__CODE__</li>",
                                'next'=>"<span>__NEXT__</span>",
                                'last'=>"<span>__LAST__</span>",
                                'select'=>"__SELECT__"
                            ); //显示语言
		protected $uri;

		/**
		 * 
		 * @access public 
		 * @param  int $totals          
		 * @param  int $pagesize        
         * @param  int $currentpage     
		 * @param  string $showstyle    
		 * @param  int $maxpage         
		 * @param  int $offset          
		 * @param  int $middlepage
		 * @param  string $pagename
		 */
		public function __construct($totals, $pagesize = null, $currentpage = null, $showstyle = null, $maxpage = null, $offset = null, $middlepage = null, $pagename = null, $pagesizeonlyread = null){
			$this->totals = $totals;
			$this->pageSize = is_null($pagesize) ? $this->pageSize : $pagesize;
			$this->showStyle = is_null($showstyle) ? $this->showStyle : strtolower($showstyle);
			$this->maxPage = is_null($maxpage) ? $this->maxPage : $maxpage;
			$this->offset = is_null($offset) ? $this->offset : $offset;
			$this->middlePage = is_null($middlepage) ? $this->middlePage : $middlepage;
			$this->pageName = is_null($pagename) ? $this->pageName : $pagename;
			$this->pageSizeOnlyRead = is_null($pagesizeonlyread) ? $this->pageSizeOnlyRead : $pagesizeonlyread;
			$this->currentPage = is_null($currentpage) ? $this->currentPage : $currentpage;
            
			$this->_init();
		}
        
        /**
         * 设置显示样式
         * @access public
         * @param  string $style
         */
         public function setShowStyle($style){
            if(!is_string($style)){
                return false;
            }
            if(strtolower($style) === 'all'){
                $this->showStyle = 'rtisfpcnl';
            }elseif(strtolower($style) === 'normal'){
                $this->showStyle = 'isfpcnl';
            }elseif(strtolower($style) === 'simple'){
                $this->showStyle = 'c';
            }else{
                $this->showStyle = $style;
            }
         }
         
        /**
         * 设置分页参数名
         * @access public
         * @param  string $PageName
         */
         public function setPageName($PageName){
            $this->pageName = is_string($PageName) ? $PageName : $this->pageName;
         }
         
        /**
         * 设置语言
         * @access public
         * @param  string $PageName
         */
         public function setLang($lang){
            $this->lang = is_array($lang) ? $lang : $this->lang;
         }
         
        /**
         * 设置省略符的偏移量
         * @access public
         * @param  string $PageName
         */
         public function setOffset($offset){
            $this->offset = is_numeric($offset) ? (int)$offset : $this->offset;
         }
         
         /**
         * 设置页码
         * @access public
         * @param  string $pageSize
         */
         public function setPageSize($pageSize){
            $this->pageSize = is_numeric($pageSize) ? (int)$pageSize : $this->pageSize;
         }
         
         /**
         * 设置省略号出现的页码
         * @access public
         * @param  string $maxPage
         */
         public function setMaxPage($maxPage){
            $this->maxPage = is_numeric($maxPage) ? (int)$maxPage : $this->maxPage;
         }
         
         /**
         * 设置省略号之间的页码数量 
         * @access public
         * @param  string $middlePage
         */
         public function setMiddlePage($middlePage){
            $this->middlePage = is_numeric($middlePage) ? (int)$middlePage : $this->middlePage;
         }
         
         /**
         * 设置页码是否只读
         * @access public
         * @param  string $pageSizeOnlyRead
         */
         public function setPageSizeOnlyRead($pageSizeOnlyRead){
            $this->pageSizeOnlyRead = is_bool($pageSizeOnlyRead) ? (boolean)$pageSizeOnlyRead : $this->pageSizeOnlyRead;
         }
         
         

		/**
		 * 获取总记录数
		 * @access public
		 * @return int
		 */
		public function getTotals(){
			return $this->totals;
		}

		/**
		 * 获取每页记录条数
		 * @access public
		 * @return int
		 */
		public function getPageSize(){
			return $this->pageSize;
		}

		/**
		 * 获取总页码
		 * @access public
		 * @return int
		 */
		public function getTotalPages(){
			return $this->totalPages;
		}


		/**
		 * 获取当前页码
		 * @access public
		 * @return int
		 */
		public function getCurrentPage(){
			return $this->currentPage;
		}

		/**
		 * 初始化
		 * @access protected
		 */
		protected function _init(){
			$this->totalPages = ceil($this->totals/$this->pageSize);
			$this->_getUri();
		}

		/**
		 * 获取uri
		 * @access protected
		 */
		protected function _getUri(){
			$uri  =  $_SERVER['REQUEST_URI'];
	        $parse = parse_url($uri);
	        if(isset($parse['query'])) {
	            parse_str($parse['query'],$params);
	            unset($params[$this->pageName]);
	            $uri   =  $parse['path'].'?'.http_build_query($params);
	        }
	        if(!empty($params))
	        {
	            $uri .= '&';
	        }
	        $this->uri = $uri;
		}

		/**
		 * 分页显示
		 * @access public
		 * @return string
		 */
		public function showPage(){
			$length = strlen($this->showStyle);
			$html = '';
			for($i = 0;$i<$length;$i++){
				$style = $this->showStyle[$i];
				switch($style){
					case self::STOTAL:
						$html .= $this->_totalHtml();
						break;
					case self::SINFO:
						$html .= $this->_infoHtml();
						break;
					case self::SRECORD:
						$html .= $this->_recordHtml();
						break;
					case self::SFIRST:
						$html .= $this->_firstHtml();
						break;
					case self::SPREV:
						$html .= $this->_prevHtml();
						break;
					case self::SCODE:
						$html .= $this->_codeHtml();
						break;
					case self::SNEXT:
						$html .= $this->_nextHtml();
						break;
					case self::SLAST:
						$html .= $this->_lastHtml();
						break;
					case self::SSELECT:
						$html .= $this->_selectHtml();
						break;
				}
			}
            return $html;
	}

	/**
	 * 总记录条数html
	 * @access protected
	 * @return string
	 */
	protected function _totalHtml(){
		$html = '';
        if(isset($this->lang['total'])){
            $html .= str_replace('__TOTALS__',$this->totals,$this->lang['total']);
        }else{
            $html .= "<span> 总计:{$this->totals}条记录</span>\n";
        }
		return $html;
	}

	/**
	 * 当前页码/总页码html
	 * @access protected
	 * @return string
	 */
	protected function _infoHtml(){
		$html = '';
        if(isset($this->lang['info'])){
            $html .= str_replace(array('__CURRENTPAGE__','__TOTALPAGES__'),array($this->currentPage,$this->totalPages),$this->lang['info']);
        }else{
            $html .= "当前第<em>{$this->currentPage}</em>页/共<em>{$this->totalPages}</em>页\n";
        }
		return $html;
	}


	/**
	 * 每页记录数
	 * @access protected
	 * @return string
	 */
	protected function _recordHtml(){
		$html = '';
		if($this->pageSizeOnlyRead){
            if(isset($this->lang['record'])){
                $html .= str_replace('__PAGESIZE__',$this->pageSize,$this->lang['record']);
            }else{
                $html .= "<span>每页{$this->pageSize}条记录</span>";
            }
		}else{
            if(isset($this->lang['record'])){
                $html .= str_replace('__PAGESIZE__',"<input name=\"pagesize\" type=\"text\" size=\"4\" value=\"{$this->pageSize}\">",$this->lang['record']);
            }else{
                $html .= "<span> 每页 <input name=\"pagesize\" type=\"text\" size=\"4\" value=\"{$this->pageSize}\"> 条记录</span>";
            }
		}
		return $html;
	}

	/**
	 * 首页html
	 * @access protected
	 * @return string
	 */
	protected function _firstHtml(){
		$html = '';
		if($this->currentPage === 1){
            if(isset($this->lang['first'])){
                preg_match('/__FIRST__@#(.*)@#/',$this->lang['first'],$text);
                $text = !empty($text[1]) ? $text[1] : '首页';
                $this->lang['first'] = str_replace('@#',"",$this->lang['first']);
                $html .= str_replace(array('__FIRST__'.$text,'__FIRST__'),"{$text}",$this->lang['first']);
            }else{
                $html .= "<span>首页</span>";
            }
		}else{
			$url = $this->uri . '&' . $this->pageName . '=1';
            if(isset($this->lang['first'])){
                preg_match('/__FIRST__@#(.*)@#/',$this->lang['first'],$text);
                $text = !empty($text[1]) ? $text[1] : '首页';
                $this->lang['first'] = str_replace('@#',"",$this->lang['first']);
                $html .= str_replace(array('__FIRST__'.$text,'__FIRST__'),"<a href=\"{$url}\">{$text}</a>",$this->lang['first']);
            }else{
                $html .= "<span><a href=\"{$url}\">首页</a></span>";
            }
		}
		return $html;
	}

	/**
	 * 上一页html
	 * @access protected
	 * @return string
	 */
	protected function _prevHtml(){
		$html = '';
		if($this->currentPage === 1){
            if(isset($this->lang['prev'])){
                preg_match('/__FIRST__@#(.*)@#/',$this->lang['prev'],$text);
                $text = !empty($text[1]) ? $text[1] : '上一页';
                $this->lang['prev'] = str_replace('@#',"",$this->lang['prev']);
                $html .= str_replace(array('__PREV__'.$text,'__PREV__'),"{$text}",$this->lang['prev']);
            }else{
                $html .= "<span>上一页</span>";
            }
		}else{
			$url = $this->uri . '&' . $this->pageName . '=' . $this->currentPage - 1;
            if(isset($this->lang['prev'])){
                preg_match('/__FIRST__@#(.*)@#/',$this->lang['prev'],$text);
                $text = !empty($text[1]) ? $text[1] : '上一页';
                $this->lang['prev'] = str_replace('@#',"",$this->lang['prev']);
                $html .= str_replace(array('__PREV__'.$text,'__PREV__'),"<a href=\"{$url}\">{$text}</a>",$this->lang['prev']);
            }else{
                $html .= "<span><a href=\"{$url}\">上一页</a></span>";
            }
		}
		return $html;
	}

	/**
	 * 页码html
	 * @access protected
	 * @return string
	 */
	protected function _codeHtml(){
		$html = '<ul>';
        $lhtml = '';
        $rhtml = '';
        $chtml = '';
				
		$middlecode1 = ceil($this->totalPages/2);
		$middlecode2 = floor($this->totalPages/2);
		if($middlecode1 === $middlecode2){
			$mincode = $middlecode1 - floor($this->offset/2);
			$maxcode = $mincode + $this->offset;
		}else{
			$mincode = $middlecode1 - floor($this->offset/2)-1;
			$maxcode = $mincode + $this->offset;
		}

		$lpage = $this->offset;
		$rpage = $this->totalPages - $this->offset;


		if($this->totalPages > $this->maxPage && $mincode > $lpage && $this->maxPage < $rpage){
			for($i=1;$i<=$this->totalPages;$i++){
				$url = $this->uri . '&' . $this->pageName . '=' . $i;

				if($i <= $lpage){
					if($i === $this->currentPage){
                        if(isset($this->lang['code'])){
                            $lhtml .= str_replace('__CODE__',$i,$this->lang['code']);
                        }else{
                            $lhtml .= "<li><span>{$i}</span></li>";
                        }
					}else{
                        if(isset($this->lang['code'])){
                            $lhtml .= str_replace('__CODE__',"<a href=\"{$url}\">{$i}</a>",$this->lang['code']);
                        }else{
                            $lhtml .= "<li><a href=\"{$url}\">{$i}</a></li>";
                        }
					}
				}else if($i >= $mincode && $i <= $maxcode){
					if($i === $this->currentPage){
                        if(isset($this->lang['code'])){
                            $chtml .= str_replace('__CODE__',$i,$this->lang['code']);
                        }else{
                            $chtml .= "<li><span>{$i}</span></li>";
                        }
					}else{
                        if(isset($this->lang['code'])){
                            $chtml .= str_replace('__CODE__',"<a href=\"{$url}\">{$i}</a>",$this->lang['code']);
                        }else{
                            $chtml .= "<li><a href=\"{$url}\">{$i}</a></li>";
                        }
					}
				}else if($i >= $rpage){
					if($i === $this->currentPage){
                        if(isset($this->lang['code'])){
                            $rhtml .= str_replace('__CODE__',$i,$this->lang['code']);
                        }else{
                            $rhtml .= "<li><span>{$i}</span></li>";
                        }
					}else{
                        if(isset($this->lang['code'])){
                            $rhtml .= str_replace('__CODE__',"<a href=\"{$url}\">{$i}</a>",$this->lang['code']);
                        }else{
                            $rhtml .= "<li><a href=\"{$url}\">{$i}</a></li>";
                        }
					}
				}
			}
            $html .= $lhtml.str_replace('__CODE__',"...",$this->lang['code']).$chtml.str_replace('__CODE__',"...",$this->lang['code']).$rhtml;
		}else if($this->totalPages > 1){
			for($i=0;$i<$this->totalPages;$i++){
				$url = $this->uri . '&' . $this->pageName . '=' . $i;
				
				if($i === $this->currentPage){
					$html .= "<li><span>{$i}</span></li>";
                    if(isset($this->lang['code'])){
                        $html .= str_replace('__CODE__',$i,$this->lang['code']);
                    }else{
                        $html .= "<li><span>{$i}</span></li>";
                    }
				}else{
                    if(isset($this->lang['code'])){
                        $html .= str_replace('__CODE__',"<a href=\"{$url}\">{$i}</a>",$this->lang['code']);
                    }else{
                        $html .= "<li><a href=\"{$url}\">{$i}</a></li>";
                    }
				}
			}
		}
		$html .= '</ul>';
		return $html;
	}

	/**
	 * 下一页html
	 * @access protected
	 * @return string
	 * 
	 */
	protected function _nextHtml(){
		$html = '';
		if($this->currentPage === $this->totalPages){
            if(isset($this->lang['next'])){
                preg_match('/__NEXT__@#(.*)@#/',$this->lang['next'],$text);
                $text = !empty($text[1]) ? $text[1] : '下一页';
                $this->lang['next'] = str_replace('@#',"",$this->lang['next']);
                $html .= str_replace(array('__NEXT__'.$text,'__NEXT__'),"{$text}",$this->lang['next']);
            }else{
               $html .= "<span>下一页</span>";
            }
		}else{
			$url = $this->uri . '&' . $this->pageName . '=' . $this->currentPage + 1;
            if(isset($this->lang['next'])){
                preg_match('/__NEXT__@#(.*)@#/',$this->lang['next'],$text);
                $text = !empty($text[1]) ? $text[1] : '下一页';
                $this->lang['next'] = str_replace('@#',"",$this->lang['next']);
                $html .= str_replace(array('__NEXT__'.$text,'__NEXT__'),"{$text}",$this->lang['next']);
            }else{
               $html .= "<span><a href=\"{$url}\">下一页</a></span>";
            }
		}
		return $html;
	}

	/**
	 * 尾页
	 * @access protected
	 * @return string
	 */
	protected function _lastHtml(){
		$html = '';
		if($this->currentPage === $this->totalPages){
            if(isset($this->lang['last'])){
                preg_match('/__LAST__@#(.*)@#/',$this->lang['last'],$text);
                $text = !empty($text[1]) ? $text[1] : '尾页';
                $this->lang['last'] = str_replace('@#',"",$this->lang['last']);
                $html .= str_replace(array('__LAST__'.$text,'__LAST__'),"{$text}",$this->lang['last']);
            }else{
               $html .= "<span>尾页</span>";
            }
		}else{
			$url = $this->uri . '&' . $this->pageName . '=' . $this->totalPages;
            if(isset($this->lang['last'])){
                preg_match('/__LAST__@#(.*)@#/',$this->lang['last'],$text);
                $text = !empty($text[1]) ? $text[1] : '尾页';
                $this->lang['last'] = str_replace('@#',"",$this->lang['last']);
                $html .= str_replace(array('__LAST__'.$text,'__LAST__'),"<a href=\"{$url}\">{$text}</a>",$this->lang['last']);
            }else{
                $html .= "<span><a href=\"{$url}\">尾页</a></span>";
            }
		}
		return $html;
	}

	/**
	 * 下拉选择框
	 * @access protected
	 * @return string
	 */
	protected function _selectHtml(){
		$html = '<select name="pageSelect">'."\n";
		for($i=1;$i<=$this->totalPages;$i++){
			$url = $this->uri . '&' . $this->pageName . '=' . $i;
			if($i === $this->currentPage){
                if(isset($this->lang['select'])){
                    $html .= str_replace('__SELECT__',"<option selected value=\"\">{$i}</option>",$this->lang['select']);
                }else{
                    $html .= "<option selected value=\"\">{$i}</option>";
                }
			}else{
                if(isset($this->lang['select'])){
                    $html .= str_replace('__SELECT__',"<option value=\"{$url}\">{$i}</option>",$this->lang['select']);
                }else{
                    $html .= "<option value=\"{$url}\">{$i}</option>";
                }
			}
		}
		$html .= '</select>';
		return $html;
	}
}